翻译 2014年12月31日 17:56:45
- **2118
接下来,我们创建自己的stack object。
创建一个名为CoreDataStack的swift加入到工程中。
转载请注明出处:http://blog.csdn.net/yamingwu/article/details/42297675
源代码地址:https://github.com/dnawym/StudySwift/tree/master/CoreData/Dog%20Walk
定义成员变量:
[cpp] view plain copy
- import CoreData
- class CoreDataStack {
- let context: NSManagedObjectContext
- let psc: NSPersistentStoreCoordinator
- let model: NSManagedObjectModel
- let store: NSPersistentStore?
- }
[cpp] view plain copy
- func saveContext() {
- var error: NSError? = nil
- if context.hasChanges && !context.save(&error) {
- println(“Could not save: (error), (error?.userInfo)”)s
- }
- }
- // 获取应用程序documents diretory的url
- func applicationDocumentsDirectory() -> NSURL {
- let fileManager = NSFileManager.defaultManager()
-
- let urls = fileManager.URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask) as [NSURL]
-
- return urls[0]
- }
[cpp] view plain copy
- init() {
- // 从硬盘加载managed object model,这里通过读取momd目录下的编译后的.xcdatamodeld文件实现
- let bundle = NSBundle.mainBundle()
- let modelURL = bundle.URLForResource(“Dog Walk”, withExtension: “momd”)
- model = NSManagedObjectModel(contentsOfURL: modelURL!)!
-
- // 一旦初始化了NSManagedObjectModel,下一步是创建PSC,PSC用于桥接model和PersistentStore
- psc = NSPersistentStoreCoordinator(managedObjectModel: model)
-
- // Context的初始化没有任何参数,我们将psc连接到context上
- context = NSManagedObjectContext()
- context.persistentStoreCoordinator = psc
-
- // 我们不需要手工创建PS,PSC会帮我们创建它。我们只需要为PSC提供所需的PS类型,一些配置,存放路径即可
- let documentsURL = applicationDocumentsDirectory()
- let storeURL = documentsURL.URLByAppendingPathComponent(“Dog Walk”)
-
- let options = [NSMigratePersistentStoresAutomaticallyOption: true]
-
- var error: NSError? = nil
- store = psc.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: options, error: &error)
-
- if store == nil {
- println(“Error adding persistent store: (error)”)
- abort()
- }
- }
修改AppDelegate文件,构造CoreData’Stack并传递给ViewController,同时添加2个函数在应用程序进入后台和即将结束时,保存数据到文件系统中
[cpp] view plain copy
- import UIKit
- import CoreData
- @UIApplicationMain
- class AppDelegate: UIResponder, UIApplicationDelegate {
-
- var window: UIWindow?
-
- lazy var coreDataStack = CoreDataStack()
- func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
- let navigationController = self.window!.rootViewController as UINavigationController
- let viewController = navigationController.topViewController as ViewController
-
- viewController.managedContext = coreDataStack.context
-
- return true
- }
-
- func applicationDidEnterBackground(application: UIApplication) {
- coreDataStack.saveContext()
- }
-
- func applicationWillTerminate(application: UIApplication) {
- coreDataStack.saveContext()
- }
- }
[cpp] view plain copy
- var managedContext: NSManagedObjectContext!
数据建模:
创建名为Dog Walk的CoreData model文件,在其中添加2个entity
这里,回到Dog Entity界面,创建一个指向walk的relationship
默认情况下,这种关系都是一对一的,这里需要修改为一对多,并且勾选Ordered,这样,数据自动按日期进行排序。
接下来,选择walk entity,创建一个inverse relationship指回dog,这里不用修改成to many,因为一次walk只会关联到一条狗
inverse的作用是让model知道如何找到反向路径。比如,对于一个walk记录,通过relationship可以找到对应的dog,通过inverse,model知道通过walks关系可以回到walk记录。通过选择右下角的按钮来切换视图模式到图像编辑模式。to-one是单箭头,to-many是双箭头。
创建ManagedObjectModel的子类,选择Dog Walk model并选择Dog和Walk这两个entity,最后记得选择swift编程语言,这样会生成Dog.swift和Walk.swift
然后,修改Dog和Walk数据模型的属性,将Dog改为Dog_Walk.Dog,将Walk改为Dog_Walk.Walk。这一步的目的是连接managed object子类的全名到data model中的entity。
实现对数据的持久存储:
前面我们已经完成了Core Data栈的创建,data model子类的创建,接下来我们修改ViewController来使用Core Data。
[cpp] view plain copy
- var currentDog: Dog!
[cpp] view plain copy
- override func viewDidLoad() {
- super.viewDidLoad()
- tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: “Cell”)
-
- let dogEntity = NSEntityDescription.entityForName(“Dog”, inManagedObjectContext: managedContext)
-
- let dog = Dog(entity: dogEntity!, insertIntoManagedObjectContext: managedContext)
-
- let dogName = “Fido”
- let dogFetch = NSFetchRequest(entityName: “Dog”)
- dogFetch.predicate = NSPredicate(format: “name == %@”, dogName)
-
- var error: NSError? = nil
- let result = managedContext.executeFetchRequest(dogFetch, error: &error) as [Dog]?
-
- if let dogs = result {
- if dogs.count == 0 {
- currentDog = Dog(entity: dogEntity!, insertIntoManagedObjectContext: managedContext)
- currentDog.name = dogName
-
- if !managedContext.save(&error) {
- println(“Could not save: (error)”)
- }
- } else {
- currentDog = dogs[0]
- }
- } else {
- println(“Could not fetch: (error)”)
- }
- }
[cpp] view plain copy
- @IBAction func add(sender: AnyObject) {
-
- // 插入新的Walk entity到Core Data中
- let walkEntity = NSEntityDescription.entityForName(“Walk”, inManagedObjectContext: managedContext)
- let walk = Walk(entity: walkEntity!, insertIntoManagedObjectContext: managedContext)
-
- walk.date = NSDate()
-
- // 插入新的walk到dog的walks集合中
- var walks = currentDog.walks.mutableCopy() as NSMutableOrderedSet
- walks.addObject(walk)
- currentDog.walks = walks.copy() as NSOrderedSet
-
- // 保存managed object context
- var error: NSError?
- if !managedContext.save(&error) {
- println(“Could not save: (error)”)
- }
-
- tableView.reloadData()
- }
从Core Data中删除数据:
添加下述函数到ViewController:
[cpp] view plain copy
- func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
- return true
- }
- func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
- if editingStyle == UITableViewCellEditingStyle.Delete {
- // 获取要删除的walk对象
- let walkToRemove = currentDog.walks[indexPath.row] as Walk
-
- // 类似于添加walk到walks,现获取一个mutable拷贝,然后在拷贝中移除对应的walk,最后将拷贝赋值回dog
- let walks = currentDog.walks.mutableCopy() as NSMutableOrderedSet
- walks.removeObjectAtIndex(indexPath.row)
- currentDog.walks = walks.copy() as NSOrderedSet
-
- // 删除walk对象
- managedContext.deleteObject(walkToRemove)
-
- // 保存
- var error: NSError?
- if !managedContext.save(&error) {
- println(“Could not save: (error)”)
- }
-
- // 从table view中删除当前行
- tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
- }
- }
至此,我们就完成了3个实例,遛狗程序。这一节中,我们学习了如何构建自己的Core Data栈,数据模型和managed object子类,以及如何建立实例之间的关系,如何操作关系以及如何从Core Data中删除数据。
接下来,我们会更深入的学习fetch和其它更高级的iOS8 topics,这一节我们学习了基本的操作,但是还有更多需要学习的地方,are you ready?